package com.gitee.funcy.disruptorlearn.ch02.quickstart;

import com.lmax.disruptor.RingBuffer;

import java.nio.ByteBuffer;

/**
 * @author fangchengyan
 * @date 2019-03-13 14:41
 */
public class OrderEventProducer {

    /**
     * RingBuffer：基于数组的缓存实现，也是创建Sequence与定义WaitStrategy的入口
     *
     * 一个首尾相接的环，在不同上下文（线程）间传递数据的buffer
     * ringBuffer拥有一个序号，这个序号指向数组中下一个可用元素
     *
     * 1. 消费者处理的速度大于生产者生产的速度，那么消费者会停下来，待生产者生产了新元素后，消费者再处理；
     * 2. 数组的长度是有限的，生产者到末尾时会再从数组的开始位置继续。这时，生产者可能会追上消费者，如果
     * 消费者还没从那个位置将数据处理完，生产者会等待消费者处理完再继续。
     *
     */
    private RingBuffer<OrderEvent> ringBuffer;

    public OrderEventProducer(RingBuffer<OrderEvent> ringBuffer) {
        this.ringBuffer = ringBuffer;
    }

    public void sendData(ByteBuffer data) {

        /**
         * 1. 通过顺序递增的序号，管理进行交换的数据（事件）
         * 2. 对数据（事件）的处理过程总是沿着序号逐个递增处理
         * 3. 一个Sequence用于跟踪标识某个特定的事件处理者（RingBuffer/Producer/Consumer）的处理进度
         */
        // 1.在生产者发送消息的时候，首先需要从ringBuffer里获取一个可用的序号
        long sequence = ringBuffer.next();
        try {
            // 2. 根据这个序号，找到具体的 “OrderEvent” 元素，注意：此时获取的OrderEvent没有被赋值
            OrderEvent event = ringBuffer.get(sequence);

            // 3. 进行实际的赋值处理
            event.setValue(data.getLong(0));
        } finally {
            // 4. 提交发布操作
            ringBuffer.publish(sequence);
        }

    }

}
